package com.xiaomi.shwx.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.common.collect.Lists;
import com.xiaomi.shwx.common.config.MinioConfig;
import com.xiaomi.shwx.common.enums.WorkOrderStatus;
import com.xiaomi.shwx.common.statemachine.WorkOrderProcessor;
import com.xiaomi.shwx.entity.pojo.WorkOrder;
import com.xiaomi.shwx.mapper.WorkOrderMapper;
import com.xiaomi.shwx.service.StorageService;
import io.minio.MinioClient;
import io.minio.ObjectWriteResponse;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * @program: after-sales-maintenance
 * @description: Minio服务实现类
 * @author: Yangziyin
 * @create: 2024-05-16 23:09
 **/
@Slf4j
@Service
public class StorageServiceImpl implements StorageService {
    @Resource
    private MinioConfig minioConfig;
    @Resource
    private WorkOrderMapper workOrderMapper;
    @Resource
    private WorkOrderProcessor workOrderProcessor;
    private MinioClient minioClient;

    @PostConstruct
    public void initialize() {
        minioClient = MinioClient.builder()
                .endpoint(minioConfig.getEndpoint())
                .credentials(minioConfig.getAccessKey(), minioConfig.getSecretKey())
                .build();
    }

    @Override
    public boolean uploadImage(String bizDesc, String orderId, MultipartFile image) {
        try {
            ObjectWriteResponse response = minioClient.putObject(PutObjectArgs.builder()
                    .bucket(minioConfig.getImageBucketName())
                    .object(generateObjectName(orderId, bizDesc, Objects.requireNonNull(image.getOriginalFilename()).split("\\.")[1]))
                    .stream(image.getInputStream(), image.getSize(), -1).build());
            String responseObject = response.object();
            // 更新数据库
            updateImage(orderId, responseObject);
            log.info("上传图片 {} 成功！", image.getOriginalFilename());
            return true;
        } catch (Exception e) {
            log.error("上传图片 {} 失败！", image.getOriginalFilename(), e);
        }
        return false;
    }

    @Override
    public boolean uploadVideo(String bizDesc, String orderId, MultipartFile video) {
        try {
            ObjectWriteResponse response = minioClient.putObject(PutObjectArgs.builder()
                    .bucket(minioConfig.getVideoBucketName())
                    .object(generateObjectName(orderId, bizDesc, Objects.requireNonNull(video.getOriginalFilename()).split("\\.")[1]))
                    .stream(video.getInputStream(), video.getSize(), -1).build());
            String responseObject = response.object();
            updateVideoName(orderId, responseObject);
            log.info("上传视频 {} 成功！", video.getOriginalFilename());
            return true;
        } catch (Exception e) {
            log.error("上传视频 {} 失败！", video.getOriginalFilename(), e);
        }
        return false;
    }

    /**
     * 随机生成文件名称
     *
     * @param bizDesc
     * @return
     */
    private String generateObjectName(String id, String bizDesc, String suffix) {
        String uuid = RandomStringUtils.randomAlphanumeric(8);
        return id + "-" + bizDesc + "-" + uuid + "." + suffix;
    }

    /**
     * 图片上传后，更新数据库
     *
     * @param id
     * @return
     */
    private synchronized void updateImage(String id, String newImageName) {
        WorkOrder workOrder = workOrderMapper.selectById(id);
        String imageName = workOrder.getImageName();
        // 更新图片名称
        if (StringUtils.isEmpty(imageName)) {
            imageName = newImageName;
        } else {
            List<String> imageNamesList = Lists.newArrayList(imageName.split(","));
            imageNamesList.add(newImageName);
            imageName = String.join(",", imageNamesList);
        }
        workOrder.setImageName(imageName);
        if (Integer.parseInt(workOrder.getStatus()) == Integer.parseInt(WorkOrderStatus.CONFIRM.getStatus())) {
            // 当前状态为“用户待确认”时，更新状态为“检测”
            workOrder.setStatus(WorkOrderStatus.CHECK.getStatus());
        }
        workOrderMapper.updateById(workOrder);
    }

    /**
     * 视频上传后，更新数据库
     *
     * @param id
     * @return
     */
    private void updateVideoName(String id, String videoName) {
        WorkOrder workOrder = workOrderMapper.selectById(id);
        workOrder.setVideoName(videoName);
        if (Integer.parseInt(workOrder.getStatus()) == Integer.parseInt(WorkOrderStatus.CHECK.getStatus())) {
            // 当前状态为“用户待确认”时，更新状态为“检测”
            workOrder.setStatus(WorkOrderStatus.RECHECK.getStatus());
        }
        workOrderMapper.updateById(workOrder);
    }
}
